
#ifndef FUNCTION_H
#define FUNCTION_H

// INCLUDES ********************************************************************

#include "Logger.h"

#include <stdint.h>

// FORWARD DECLARATIONS ********************************************************



/*******************************************************************************
 
 TODO:  
 
*******************************************************************************/

// *****************************************************************************

//! Function
//! 
//! Dirty template hacking to allow callbacks with different parameters

// *****************************************************************************

namespace Meteor
{
    class Function
    {
        public:
            virtual void operator()()
            {
            }
    };
    
    // -------------------------------------------------------------------------

    template <typename Class, typename Parameter>
    class MemberFunction : public Function
    {
        typedef void ( Class::*MemFunc)( Parameter);
    
        public:
            MemberFunction( Class* object, MemFunc function, Parameter param)
            : mCallee( object), mMemberFunction( function), mParameter( param)
            {
            }
        
            MemberFunction( const MemberFunction& old);
        
            const MemberFunction& operator=( const MemberFunction& rhs);
        
             void operator()()
            {
                ( mCallee->*mMemberFunction)( mParameter);
            }
        
            void operator()( Parameter param)
            {
                ( mCallee->*mMemberFunction)( param);
            }
        
        private:
            void Copy( const MemberFunction& old);
        
            Class* mCallee;
        
            MemFunc mMemberFunction;
        
            Parameter mParameter;
    };
    
    // -------------------------------------------------------------------------
    
    template <typename Class>
    class MemberFunction<Class, void> : public Function
    {
        typedef void (Class::*MemFunc)();
        
        public:
            MemberFunction( Class* object, MemFunc MemberFunction)
            : mCallee( object), mMemberFunction( MemberFunction)
            {
            }
        
            MemberFunction( const MemberFunction& old);
        
            const MemberFunction& operator=( const MemberFunction& rhs);
        
            void operator()()
            {
                ( mCallee->*mMemberFunction)();
            }
        
        private:
            void Copy( const MemberFunction& old);
        
            Class* mCallee;
        
            MemFunc mMemberFunction;
        
    }; // end of class MemberFunction
    
} // end of namespace Meteor


#endif